package net.jueb.protoServer.protocol;

import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.MessageToByteEncoder;
import io.netty.handler.codec.MessageToMessageDecoder;
import io.netty.handler.codec.MessageToMessageEncoder;

import java.util.concurrent.ConcurrentHashMap;

import net.jueb.protoServer.controller.ServiceController;
import net.jueb.protoServer.handler.dispatcher.MessageDispatcherHandler;
import net.jueb.protoServer.message.mapping.MessageMapping;

/**
 * 端口协议模块
 * 用来规范一系列解码编码和分发器之间的消息类型统一
 */
public abstract class PortProtocol<M> {
	/**
	 * 该协议使用的消息处理控制器
	 */
	protected final ConcurrentHashMap<Integer,ServiceController<?>> controllers=new ConcurrentHashMap<Integer,ServiceController<?>>();
	/**
	 * 默认消息分发器
	 */
	private final MessageDispatcherHandler<M> defaultDispatcher;
	
	
	public PortProtocol() {
		defaultDispatcher=new DefaultDispatcher(controllers);
	}
	
	/**
	 * 使用当前类型的默认分发器
	 * @author Administrator
	 */
	private class DefaultDispatcher extends MessageDispatcherHandler<M>
	{
		public DefaultDispatcher(ConcurrentHashMap<Integer, ServiceController<?>> controllers) {
			super(controllers);
		}
	}
	
	/**
	 * 用于消息组包的handler
	 * @return
	 */
	public abstract ByteToMessageDecoder getMessageUnPackHandler();
	
	/**
	 * 用于ByteBuf到消息类型解码的handler
	 * @return
	 */
	public abstract MessageToMessageDecoder<ByteBuf> getMessageDecoderHandler();
	
	/**
	 * 用于消息到ByteBuf封包的handler
	 * @return
	 */
	public abstract MessageToByteEncoder<ByteBuf> getMessagePackHandler();
	/**
	 * 用于消息解码的handler
	 * @return
	 */
	public abstract MessageToMessageEncoder<?> getMessageEncoderHandler();
	
	/**
	 * 返回一个该消息协议使用的映射器
	 * @return
	 */
	public abstract MessageMapping<M> getMessageMapping();
	
	/**
	 * 使用默认类型的分发器
	 * @return
	 */
	public MessageDispatcherHandler<M> getMessageDispatcher()
	{
		return this.defaultDispatcher;
	}
	
	public final ConcurrentHashMap<Integer, ServiceController<?>> getServiceControllers()
	{
		return this.controllers;
	}
}
